package com.mokairui.completable_future;

import com.mokairui.util.SmallTool;

import java.util.concurrent.CompletableFuture;

/**
 * @author Mokairui
 * @Description
 *                  thenApply: 将上一个异步任务的结果交给下一个线程
 *                  thenApplySync: 不等上一个任务执行完，也就是异步的意思
 *                  applyToEither(CompletableStage, Function): 两个异步任务，谁先执行完就将谁的结果通过Function进行传递
 *                  exceptionally: 异常处理
 * @Since 2021/7/4
 */
public class CompletableFutureDemo2 {
    public static void main(String[] args) {
        SmallTool.printThreadAndTime("小白吃好了");
        SmallTool.printThreadAndTime("小白要求结账，开发票");

        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            SmallTool.printThreadAndTime("服务员收款500元");
            SmallTool.sleepMills(100);
            return "500";
        }).thenApply(money -> {
            SmallTool.printThreadAndTime(String.format("服务员开发票，面额%s元", money));
            SmallTool.sleepMills(200);
            return String.format("%s元面额发票", money);
        });

        SmallTool.printThreadAndTime("小白接到电话想和朋友一起打游戏");
        SmallTool.printThreadAndTime(String.format("小白拿到%s,准备回家", future.join()));

        CompletableFuture<String> futureBus = CompletableFuture.supplyAsync(() -> {
            SmallTool.printThreadAndTime("700路公交车正在赶来");
            SmallTool.sleepMills(100);
            return "700路";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            SmallTool.printThreadAndTime("800路公交车正在赶来");
            SmallTool.sleepMills(200);
            return "800路";
        }), firstBus -> {
            SmallTool.printThreadAndTime(firstBus);
            if (firstBus.startsWith("700路")) {
                throw new RuntimeException("700路公交车撞树了");
            }
            return firstBus;
        }).exceptionally(e -> {
            SmallTool.printThreadAndTime(e.getMessage());
            SmallTool.printThreadAndTime("小白叫出租车");
            return "出租车叫到了";
        });

        SmallTool.printThreadAndTime(String.format("%s,小白坐车回家", futureBus.join()));
    }
}
